#ifndef __FT6X36_UPGRADE_FIRMWARE_H
#define __FT6X36_UPGRADE_FIRMWARE_H

#ifdef __cplusplus
extern "C" {
#endif

/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define FTS_AUTO_UPGRADE_EN                         1
#define FTS_CMD_RESET                               0x07
#define FTS_ROMBOOT_CMD_SET_PRAM_ADDR               0xAD
#define FTS_ROMBOOT_CMD_SET_PRAM_ADDR_LEN           4
#define FTS_ROMBOOT_CMD_WRITE                       0xAE
#define FTS_ROMBOOT_CMD_START_APP                   0x08
#define FTS_DELAY_PRAMBOOT_START                    100
#define FTS_ROMBOOT_CMD_ECC                         0xCC
#define FTS_PRAM_SADDR                              0x000000
#define FTS_DRAM_SADDR                              0xD00000

#define FTS_CMD_READ_FWCFG                          0xA8

#define FTS_CMD_READ                                0x03
#define FTS_CMD_READ_DELAY                          1
#define FTS_CMD_READ_LEN                            4
#define FTS_CMD_READ_LEN_SPI                        6
#define FTS_CMD_FLASH_TYPE                          0x05
#define FTS_CMD_FLASH_MODE                          0x09
#define FLASH_MODE_WRITE_FLASH_VALUE                0x0A
#define FLASH_MODE_UPGRADE_VALUE                    0x0B
#define FLASH_MODE_LIC_VALUE                        0x0C
#define FLASH_MODE_PARAM_VALUE                      0x0D
#define FTS_CMD_ERASE_APP                           0x61
#define FTS_REASE_APP_DELAY                         1350
#define FTS_ERASE_SECTOR_DELAY                      60
#define FTS_RETRIES_REASE                           50
#define FTS_RETRIES_DELAY_REASE                     400
#define FTS_CMD_FLASH_STATUS                        0x6A
#define FTS_CMD_FLASH_STATUS_LEN                    2
#define FTS_CMD_FLASH_STATUS_NOP                    0x0000
#define FTS_CMD_FLASH_STATUS_ECC_OK                 0xF055
#define FTS_CMD_FLASH_STATUS_ERASE_OK               0xF0AA
#define FTS_CMD_FLASH_STATUS_WRITE_OK               0x1000
#define FTS_CMD_ECC_INIT                            0x64
#define FTS_CMD_ECC_CAL                             0x65
#define FTS_CMD_ECC_CAL_LEN                         7
#define FTS_RETRIES_ECC_CAL                         10
#define FTS_RETRIES_DELAY_ECC_CAL                   50
#define FTS_CMD_ECC_READ                            0x66
#define FTS_CMD_DATA_LEN                            0xB0
#define FTS_CMD_APP_DATA_LEN_INCELL                 0x7A
#define FTS_CMD_DATA_LEN_LEN                        4
#define FTS_CMD_SET_WFLASH_ADDR                     0xAB
#define FTS_CMD_SET_RFLASH_ADDR                     0xAC
#define FTS_LEN_SET_ADDR                            4
#define FTS_CMD_WRITE                               0xBF
#define FTS_RETRIES_WRITE                           100
#define FTS_RETRIES_DELAY_WRITE                     1
#define FTS_CMD_WRITE_LEN                           6
#define FTS_DELAY_READ_ID                           20
#define FTS_DELAY_UPGRADE_RESET                     80
#define PRAMBOOT_MIN_SIZE                           0x120
#define PRAMBOOT_MAX_SIZE                           (64*1024)
#define FTS_FLASH_PACKET_LENGTH                     32     /* max=128 */
#define FTS_MAX_LEN_ECC_CALC                        0xFFFE /* must be even */
#define FTS_MIN_LEN                                 0x120
#define FTS_MAX_LEN_FILE                            (256 * 1024)
#define FTS_MAX_LEN_APP                             (64 * 1024)
#define FTS_MAX_LEN_SECTOR                          (4 * 1024)
#define FTS_CONIFG_VENDORID_OFF                     0x04
#define FTS_CONIFG_MODULEID_OFF                     0x1E
#define FTS_CONIFG_PROJECTID_OFF                    0x20
#define FTS_APPINFO_OFF                             0x100
#define FTS_APPINFO_APPLEN_OFF                      0x00
#define FTS_APPINFO_APPLEN2_OFF                     0x12
#define FTS_REG_UPGRADE                             0xFC
#define FTS_REG_UPGRADE2                            0xBC
#define FTS_UPGRADE_AA                              0xAA
#define FTS_UPGRADE_55                              0x55
#define FTS_DELAY_UPGRADE_AA                        10
#define FTS_UPGRADE_LOOP                            30
#define FTS_HEADER_LEN                              32
#define MAX_MODULE_VENDOR_NAME_LEN                  16

#define FTS_ROMBOOT_CMD_ECC_NEW_LEN                 7
#define FTS_ECC_FINISH_TIMEOUT                      100
#define FTS_ROMBOOT_CMD_ECC_FINISH                  0xCE
#define FTS_ROMBOOT_CMD_ECC_FINISH_OK_A5            0xA5
#define FTS_ROMBOOT_CMD_ECC_FINISH_OK_00            0x00
#define FTS_ROMBOOT_CMD_ECC_READ                    0xCD
#define AL2_FCS_COEF                ((1 << 15) + (1 << 10) + (1 << 3))

#define FTS_APP_INFO_OFFSET                         0x100
#define FTS_MAX_COMPATIBLE_TYPE             4

#define FTS_CMD_READ_ID                             0x90

/* chip id */
#define FTS_CHIP_IDH                                0x52
#define FTS_CHIP_IDL                                0x60

enum FW_STATUS {
    FTS_RUN_IN_ERROR,
    FTS_RUN_IN_APP,
    FTS_RUN_IN_ROM,
    FTS_RUN_IN_PRAM,
    FTS_RUN_IN_BOOTLOADER,
};

enum FW_FLASH_MODE {
    FLASH_MODE_APP,
    FLASH_MODE_LIC,
    FLASH_MODE_PARAM,
    FLASH_MODE_ALL,
};

enum ECC_CHECK_MODE {
    ECC_CHECK_MODE_XOR,
    ECC_CHECK_MODE_CRC16,
};

enum UPGRADE_SPEC {
    UPGRADE_SPEC_V_1_0 = 0x0100,
    UPGRADE_SPEC_V_1_1 = 0x0101,
    UPGRADE_SPEC_V_1_2 = 0x0102,
};

/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
/* IC info */
struct upgrade_func {
    unsigned short ctype[FTS_MAX_COMPATIBLE_TYPE];
    unsigned int fwveroff;
    unsigned int fwcfgoff;
    unsigned int appoff;
    unsigned int licoff;
    unsigned int paramcfgoff;
    unsigned int paramcfgveroff;
    unsigned int paramcfg2off;
    int pram_ecc_check_mode;
    int fw_ecc_check_mode;
    int upgspec_version;
    unsigned char *pramboot;
    unsigned int pb_length;
    int (*init)(unsigned char *, unsigned int);
    int (*write_pramboot_private)(void);
    int (*upgrade)(unsigned char *, unsigned int);
    int (*get_hlic_ver)(unsigned char *);
    int (*lic_upgrade)(unsigned char *, unsigned int);
    int (*param_upgrade)(unsigned char *, unsigned int);
    int (*force_upgrade)(unsigned char *, unsigned int);
};

struct upgrade_setting_nf {
    unsigned char rom_idh;
    unsigned char rom_idl;
    unsigned short reserved;
    unsigned int app2_offset;
    unsigned int ecclen_max;
    unsigned char eccok_val;
    unsigned char upgsts_boot;
    unsigned char delay_init;
    unsigned char spi_pe;
    unsigned char length_coefficient;
    unsigned char fd_check;
    unsigned char drwr_support;
    unsigned char ecc_delay;
};

struct upgrade_module {
    int id;
    char vendor_name[MAX_MODULE_VENDOR_NAME_LEN];
    unsigned char *fw_file;
    unsigned int fw_len;
};

struct fts_upgrade {
    struct upgrade_module *module_info;
    struct upgrade_func *func;
    struct upgrade_setting_nf *setting_nf;
    int module_id;
    unsigned char *fw;
    unsigned int fw_length;
    unsigned char *lic;
    unsigned int lic_length;
};

/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
extern struct upgrade_func upgrade_func_ft6x36;
extern struct fts_upgrade fwupgrade;

/*****************************************************************************
* Static function prototypes
*****************************************************************************/
int fts_fwupg_reset_in_boot(void);
int fts_fwupg_enter_into_boot(void);
int fts_fwupg_erase(unsigned int delay);
int fts_fwupg_ecc_cal(unsigned int saddr, unsigned int len);
int fts_flash_write_buf(unsigned int saddr, unsigned char *buf, unsigned int len, unsigned int delay);
int fts_flash_read_buf(unsigned int saddr, unsigned char *buf, unsigned int len);
int fts_fwupg_upgrade(struct fts_upgrade *upg);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif
